package view.GUI.adminView.coreData.product;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import model.data.interfaces.IFinishable;
import model.data.tableModel.TableControl;
import model.data.tableModel.sale.Product;
import view.GUI.adminView.coreData.people.EditBox;
import view.GUI.mainView.KindVBox.BoxType;
import view.GUI.mainView.MainView;
import view.Validator.MyValidationSupport;
import enums.GUIText;
import enums.Status;

public final class EditProduct extends AbstractProductView {

	private EditBox editbox;
	private Label lblReplacement;
	private TableView<Product> table;

	public EditProduct(MainView instance, GUIText title) {
		super(true, instance, GUIText.EDITPRODUCT);
		setupTable();

		List<Product> list = new ArrayList<>();
		for (BoxType bt : BoxType.values()) {
			list.addAll(owner.getProducts(false, bt));
		}
		Collections.sort(list);
		this.editbox = new EditBox(super.valSup, GUIText.PRODUCT, list);
		ComboBox<IFinishable> cmb = editbox.getComboBox();
		cmb.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<IFinishable>() {

			@Override
			public void changed(ObservableValue<? extends IFinishable> observable, IFinishable oldValue, IFinishable newValue) {
				setupProduct((Product) newValue);
				table.getItems().clear();
				table.getItems().addAll(owner.getProductGroup(((Product) newValue).getGroupID()));
				btnSave.setDisable(MyValidationSupport.isNodeToDisable(valSup));
			}
		});
		int columnCounter = 0;
		for (Node n : editbox.getNodes()) {
			super.addNode(n, columnCounter++, 0);
		}
		super.cmbDeposit.setDisable(true);
		try {
			start(new Stage());
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
	}

	private void setupTable() {
		lblReplacement = new Label(GUIText.REPLACEMENTTABLE.toString());
		super.addNode(lblReplacement, 0, 1);

		table = new TableView<>();
		table.setPrefHeight(100);
		table.setEditable(true);

		TableColumn<Product, Double> costCol = new TableColumn<>(GUIText.COST.toString());
		costCol.setCellValueFactory(new PropertyValueFactory<Product, Double>("cost"));
		costCol.setMinWidth(125);

		TableColumn<Product, Double> salePriceCol = new TableColumn<>(GUIText.SALEPRICE.toString());
		salePriceCol.setMinWidth(125);
		salePriceCol.setCellValueFactory(new PropertyValueFactory<Product, Double>("salePrice"));

		TableColumn<Product, String> stockCol = new TableColumn<>(GUIText.STOCK.toString());
		stockCol.setMinWidth(125);
		stockCol.setCellFactory(TextFieldTableCell.forTableColumn());
		stockCol.setCellValueFactory(new PropertyValueFactory<Product, String>("stockTable"));
		stockCol.setOnEditCommit(new EventHandler<CellEditEvent<Product, String>>() {

			@Override
			public void handle(CellEditEvent<Product, String> t) {
				Product p = (t.getTableView().getItems().get(t.getTablePosition().getRow()));
				p.setStock(Integer.valueOf((t.getNewValue())));
			}
		});
		
		TableColumn<Product, String> trayCol = new TableColumn<>(GUIText.TRAYCOUNT.toString());
		trayCol.setMinWidth(175);
		trayCol.setCellFactory(TextFieldTableCell.forTableColumn());
		trayCol.setCellValueFactory(new PropertyValueFactory<Product, String>("trayTable"));
		trayCol.setOnEditCommit(new EventHandler<CellEditEvent<Product, String>>() {

			@Override
			public void handle(CellEditEvent<Product, String> t) {
				Product p = (t.getTableView().getItems().get(t.getTablePosition().getRow()));
				p.setTrayCount(Integer.valueOf((t.getNewValue())));
				p.writeUpdateToDB();
			}
		});

//		table.getColumns().addAll(costCol, salePriceCol, stockCol, trayCol);
		table.getColumns().add(costCol);
		table.getColumns().add(salePriceCol);
		table.getColumns().add(stockCol);
		table.getColumns().add(trayCol);

		GridPane.setColumnSpan(table, 3);
		super.addNode(table, 0, 2);
	}

	private void setupProduct(Product p) {
		super.txtName.setText(p.getName());
		super.txtCost.setText(String.valueOf(p.getCost()));
		super.txtSalePrice.setText(String.valueOf(p.getSalePrice()));
		super.cmbCategory.getSelectionModel().select(p.getCategory());
		super.cmbDeposit.getSelectionModel().select(p.getDeposit());
		super.txtStock.setText(String.valueOf(p.getStock()));
		super.txtMaxStock.setText(String.valueOf(p.getMaxStock()));
		super.txtMultiplicator.setText(String.valueOf(p.getMultiplicator()));
		super.txtTrayCount.setText(String.valueOf(p.getTrayCount()));
	}

	@Override
	protected boolean save() {
		if (editbox.isDeleteSelected()) {
			Product p = (Product) editbox.getComboBox().getSelectionModel().getSelectedItem();
			p.setStatus(Status.INACTIVE);
			TableControl.getInstance().getProductMap().remove(p.getID(), p.getName());
			return p.writeUpdateToDB();

		} else {
			Product selected = ((Product) editbox.getComboBox().getSelectionModel().getSelectedItem());
			selected.setStock(Integer.valueOf(super.txtStock.getText()));
			selected.setMaxStock(Integer.valueOf(super.txtMaxStock.getText()));
			selected.setName(super.txtName.getText());
			selected.setCategory(super.cmbCategory.getSelectionModel().getSelectedItem());
			selected.setTrayCount(Integer.valueOf(super.txtTrayCount.getText()));
			selected.setMultiplicator(Integer.valueOf(super.txtMultiplicator.getText()));

			if (selected.getCost() != Double.valueOf(super.txtCost.getText())
					|| selected.getSalePrice() != Double.valueOf(super.txtSalePrice.getText())) {
				Product newProduct = selected.changePurchaseConditions(Double.valueOf(super.txtCost.getText()),
						Double.valueOf(super.txtSalePrice.getText()));
				
				if (selected.getStatus().equals(Status.INACTIVE)) {
					owner.deleteProduct(selected);
				}
				if (newProduct != null) {
					owner.addProduct(newProduct);
				}
				return true;
			} else {
				return selected.writeUpdateToDB();
			}
		}
	}
}
